package com.suning.park.admin.mgr.ordermanager.service.impl;

import com.google.common.collect.Lists;
import com.suning.park.dto.dao.OrderPayMapper;
import com.suning.park.dto.dao.ParkOrderMapper;
import com.suning.park.dto.model.OrderPay;
import com.suning.park.dto.model.OrderPayExample;
import com.suning.park.dto.model.ParkOrder;
import com.suning.park.dto.model.ParkOrderExample;
import com.suning.park.admin.databasespec.model.SpecParkUserOrder;
import com.suning.park.admin.enums.ParkOrderTypeEnum;
import com.suning.park.admin.util.page.PageInfo;
import com.suning.park.admin.databasespec.dao.SpecParkOrderMapper;
import com.suning.park.admin.databasespec.model.SpecParkOrder;
import com.suning.park.admin.enums.RecvChannelEnum;
import com.suning.park.admin.exception.BusinessFailException;
import com.suning.park.admin.mgr.ordermanager.model.ParkOrderExcel;
import com.suning.park.admin.mgr.ordermanager.service.OrderManagerService;
import com.suning.park.admin.util.BigDecimalUtil;
import com.suning.park.admin.util.CheckValue;
import com.suning.park.admin.util.DateUtil;
import com.suning.park.admin.util.JsonUtil;
import com.suning.park.admin.util.excelTools.ExcelUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/*
 * Author:   niecheng
 * Date:     2017/1/19 11:20
 * Project:  park-pom
 * Description: //订单管理服务接口实现
 */
@Service(value = "orderManagerServiceImpl")
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class OrderManagerServiceImpl implements OrderManagerService {


    private static final Logger logger = LoggerFactory.getLogger(OrderManagerServiceImpl.class);

    @Autowired
    ParkOrderMapper parkOrderMapper;
    @Autowired
    OrderPayMapper orderPayMapper;

    @Autowired
    SpecParkOrderMapper specParkOrderMapper;

    @Override
    public PageInfo ajaxParkOrderList(PageInfo pageInfo, ParkOrder parkOrder) {
        //TODO 获取支付订单信息
        final ParkOrderExample parkOrderExample = getParkOrderExampleHandle(parkOrder);
        final int curParkOrderCount = queryParkOrderCount(parkOrderExample);
        List<ParkOrder> parkOrders = getParkOrder(pageInfo, parkOrderExample);
        pageInfo.setResultObject(parkOrders);
        pageInfo.setTotalResult( CheckValue.isEmpty(parkOrders) ? 0 : curParkOrderCount);
        return pageInfo;
    }

    @Override
    public PageInfo ajaxParkOrderDailyList(PageInfo pageInfo, String parkId, String payType,  String queryTime) {
        //TODO 获取临停车辆收费日报表
        final Map<String, Object> param = new HashMap<>();
        param.put("page", pageInfo);
        param.put("parkId", parkId);
        param.put("payType", payType);
        param.put("queryTime", queryTime);
        final List<SpecParkOrder> specParkOrders = specParkOrderMapper.selectByMap(param);
        logger.info("返回结果：长度：{} {}", new Object[]{specParkOrders.size(), JsonUtil.objectToJson(specParkOrders)});
        pageInfo.setResultObject(specParkOrders);
        return pageInfo;
    }

    @Override
    public SpecParkUserOrder getOrderPay(String parkOrderId, String queryDate) {
        //TODO 获取支付明细
        final Map<String, Object> param = new HashMap<>();
        param.put("parkOrderId", parkOrderId);
        param.put("queryDate", queryDate);
        final List<SpecParkUserOrder> specParkUserOrders = specParkOrderMapper.selectBaseDataByMap(param);
        return CheckValue.isEmpty(specParkUserOrders) ? new SpecParkUserOrder() : specParkUserOrders.get(0);
    }

    @Override
    public byte[] exportPayOrderList(ParkOrder parkOrder) {
        final ParkOrderExample parkOrderExample = getParkOrderExampleHandle(parkOrder);
        List<ParkOrder> parkOrders = parkOrderMapper.selectByExample(parkOrderExample);
        final List<Object> excelData = getExcelData(parkOrders);
        return getByteArrayOutputStream(excelData).toByteArray();
    }

    /**
     * 获取要下载的数据
     * @return
     */
    private List<Object> getExcelData(List<ParkOrder> parkOrders){
        List<Object> results = Lists.newArrayList();
        ParkOrderExcel parkOrderExcel = null;
        for (ParkOrder parkOrder : parkOrders){
            parkOrderExcel = new ParkOrderExcel();
            parkOrderExcel.setParkOrderId(parkOrder.getId());
            parkOrderExcel.setOrderType(ParkOrderTypeEnum.getText(parkOrder.getOrderType()));
            parkOrderExcel.setCarNum(parkOrder.getCarNum());
            parkOrderExcel.setParkTime(parkOrder.getParkTime());
            parkOrderExcel.setRecvChannel(RecvChannelEnum.getText(parkOrder.getRecvChannel()));
            parkOrderExcel.setParkAmount(BigDecimalUtil.toString(parkOrder.getParkAmount()));
            parkOrderExcel.setSuccessTime(DateUtil.format(parkOrder.getSuccessTime(), DateUtil.datetimeFormat));
            results.add(parkOrderExcel);
        }
        return results;
    }

    /**
     * 导出收费订单明细数据字节数据缓存
     * @param dataList
     * @return
     */
    public ByteArrayOutputStream getByteArrayOutputStream(List<Object> dataList){
        ByteArrayOutputStream out = null;
        try {
            String[] headers = {"订单号","订单状态","车牌号","停放时长( 小时 )","收费渠道","收费金额 ( 元 )","收费日期"};
            HSSFWorkbook workbook = ExcelUtil.exportExcelByListModel("临停车收费订单明细", headers, dataList,null);
            out = new ByteArrayOutputStream();
            HSSFWorkbook hssWb = (HSSFWorkbook) workbook;
            hssWb.write(out);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return out;
    }

    /**
     * 查询支付明细
     * @param parkOrderId
     * @return
     */
    public List<OrderPay> selectOrderPay(String parkOrderId){
        final OrderPayExample orderPayExample = new OrderPayExample();
        final OrderPayExample.Criteria criteria = orderPayExample.createCriteria();
        criteria.andIdEqualTo(parkOrderId);
        return orderPayMapper.selectByExample(orderPayExample);
    }

    /**
     * 获取支付订单数据
     *
     * @param pageInfo         分页信息
     * @param parkOrderExample 查询支付订单条件
     * @return
     */
    public List<ParkOrder> getParkOrder(PageInfo pageInfo, ParkOrderExample parkOrderExample) {
        parkOrderExample.setLimitStart((pageInfo.getCurrentPage() - 1) * pageInfo.getShowCount());
        parkOrderExample.setLimitRows(pageInfo.getShowCount());
        return parkOrderMapper.selectByExample(parkOrderExample);
    }

    /**
     * 获取支付订单数据总量
     *
     * @param parkOrderExample 支付订单查询条件
     * @return
     */
    public int queryParkOrderCount(ParkOrderExample parkOrderExample) {
        List<ParkOrder> parkOrders = parkOrderMapper.selectByExample(parkOrderExample);
        return CheckValue.isEmpty(parkOrders) ? 0 : parkOrders.size();
    }

    /**
     * 获取支付订单查询条件Example
     * @param parkOrder 支付订单条件
     * @return
     */
    public static ParkOrderExample getParkOrderExampleHandle(ParkOrder parkOrder) {
        ParkOrderExample parkOrderExample = new ParkOrderExample();
        ParkOrderExample.Criteria criteria = parkOrderExample.createCriteria();
        if (!CheckValue.isEmpty(parkOrder.getParkId())) {
            criteria.andParkIdEqualTo(parkOrder.getParkId());
        }
        if (!CheckValue.isEmpty(parkOrder.getOrderType())) {
            criteria.andOrderTypeEqualTo(parkOrder.getOrderType());
        }
        if (!CheckValue.isEmpty(parkOrder.getRecvChannel())) {
            criteria.andRecvChannelEqualTo(parkOrder.getRecvChannel());
        }
        if (!CheckValue.isEmpty(parkOrder.getCarNum())) {
            criteria.andCarNumEqualTo(parkOrder.getCarNum());
        }

        if (!CheckValue.isEmpty(parkOrder.getSuccessTime())) {
            final Date successTime = parkOrder.getSuccessTime();
            try {
                criteria.andSuccessTimeBetween(DateUtil.getAddTime(successTime, "000000"), DateUtil.getAddTime(successTime, "235959"));
            } catch (ParseException e) {
                logger.error("时间转换异常, 错误信息：{}", e.getMessage());
                //TODO 如果日期格式处理异常，则时间段改当前时间去获取数据，避免拉取过长数据或者导出EXCEL内容过多导致内存溢出；避免直接抛异常
//                criteria.andSuccessTimeEqualTo(parkOrder.getSuccessTime());
                throw new BusinessFailException("系统异常");
            }
        }
        if (!CheckValue.isEmpty(parkOrder.getOperatorName())) {
            criteria.andOperatorNameEqualTo(parkOrder.getOperatorName());
        }
        return parkOrderExample;
    }

    @Override
    public List<ParkOrder> selectByExample(ParkOrderExample example) {
        return parkOrderMapper.selectByExample(example);
    }
}
